// Kony


#include "AbilitySystem/Abilitys/BaseFireBolt.h"

#include "AbilitySystem/BaseAbilitySystemLibrary.h"
#include "Actor/BaseProjectile.h"
#include "Interaction/CombatInterface.h"
#include "GameFramework/ProjectileMovementComponent.h"


//当前技能描述
FString UBaseFireBolt::GetDescription(int32 Level, const FText& Title, const FText& Description)
{
	const float ScaledDamage = Damage.GetValueAtLevel(Level);
	TArray<FStringFormatArg> Args;
	Args.Add(FStringFormatArg(FString::Printf(TEXT("%.1f"), ScaledDamage)));
	Args.Add(FStringFormatArg(FString::Printf(TEXT("%.1f"), FMath::Abs(GetManaCost(Level)))));
	Args.Add(FStringFormatArg(FString::Printf(TEXT("%.1f"), GetCooldown(Level))));
	Args.Add(FStringFormatArg(Level));
	Args.Add(FStringFormatArg(FMath::Min(Level, NumProjectiles)));
	return FormatAbilityDescription(Level, Title, Description, Args);
}
//下一级技能描述
FString UBaseFireBolt::GetNextLevelDescription(int32 Level, const FText& Title, const FText& Description)
{
	const float ScaledDamage = Damage.GetValueAtLevel(Level);
	TArray<FStringFormatArg> Args;
	Args.Add(FStringFormatArg(FString::Printf(TEXT("%.1f"), ScaledDamage)));
	Args.Add(FStringFormatArg(FString::Printf(TEXT("%.1f"), FMath::Abs(GetManaCost(Level)))));
	Args.Add(FStringFormatArg(FString::Printf(TEXT("%.1f"), GetCooldown(Level))));
	Args.Add(FStringFormatArg(Level));
	Args.Add(FStringFormatArg(FMath::Min(Level, NumProjectiles)));
	return FormatNextLevelDescription(Level, Title, Description, Args);
}
//创建 发射火球术
void UBaseFireBolt::SpawnProjectiles(const FVector& ProjectileTargetLocation, const FGameplayTag& SocketTag, bool bOverridePitch, float PitchOverride, AActor* HomingTarget)
{
	//使用蓝图库进行智能目标选择和转向 这个要在服务器执行前进行 否则客户端无法转向
	AActor* FinalHomingTarget = HomingTarget;
	FVector FinalProjectileTargetLocation = ProjectileTargetLocation;
	
	// 如果当前发射位置方向与 HomingTarget 指向的方向不同，则让玩家面向 HomingTarget（仅Yaw）
	// 这个逻辑需要在客户端和服务端都执行，确保转向同步
	//蓝图中就能实现 不需要在这里用了
	// if (FinalHomingTarget && IsValid(GetAvatarActorFromActorInfo()))
	// {
	// 	// 确保发射方向指向锁定目标
	// 	FinalProjectileTargetLocation = UBaseAbilitySystemLibrary::RotatePlayerToTarget(GetAvatarActorFromActorInfo(), FinalHomingTarget,FinalProjectileTargetLocation, 5.0f);
	// }

	//判断是否是处于服务器
	const bool bIsServer = GetAvatarActorFromActorInfo()->HasAuthority();
	if (!bIsServer) return;

	const FVector SocketLocation = ICombatInterface::Execute_GetCombatSocketLocation(
			GetAvatarActorFromActorInfo(),
			SocketTag,false,150.0f);
		
	//计算投射物发射方向
	FRotator Rotation = (FinalProjectileTargetLocation - SocketLocation).Rotation();
	//如果需要，可以在蓝图中设置投射物发射方向 调整俯仰角值 PitchOverride
	if (bOverridePitch) Rotation.Pitch = PitchOverride;
	//通过等级 计算投射物数量，并且取最小值
	const int32 EffectiveNumProjectiles = FMath::Min(MaxNumProjectiles,GetAbilityLevel());
	//旋转点向量
	const FVector Forward = Rotation.Vector();
	//按数量线性扩张夹角，最大为 ProjectileSpread
	const float SpreadScale = (EffectiveNumProjectiles > 1 && MaxNumProjectiles > 1)
		? float(EffectiveNumProjectiles - 1) / float(MaxNumProjectiles - 1)
		: 0.f;
	const float ActualSpread = ProjectileSpread * SpreadScale;
	//获取均匀分布 旋转器数组
	TArray<FRotator> RotatorArray = UBaseAbilitySystemLibrary::EvenlySpacedRotators(Forward,FVector::UpVector, ActualSpread, EffectiveNumProjectiles);
	
	for (FRotator& Rot : RotatorArray)
	{
		FTransform SpawnTransform;
		SpawnTransform.SetLocation(SocketLocation);
		//设置投射物方向旋转 这样就可以让投射物向目标飞行
		SpawnTransform.SetRotation(Rot.Quaternion());
		
		ABaseProjectile* Projectile = GetWorld()->SpawnActorDeferred<ABaseProjectile>(
			ProjectileClass,
			SpawnTransform,
			GetOwningActorFromActorInfo(),
			Cast<APawn>(GetOwningActorFromActorInfo()),
			ESpawnActorCollisionHandlingMethod::AlwaysSpawn);
		//设置伤害效果参数,这里目标演员暂时不知道是谁 所以默认空值
		Projectile->DamageEffectParams =  MakeDamageEffectParamsFromClassDefaults();
		
		//判断是否启用了追踪敌人
		if (bIsHoming)
		{
			if (HomingTarget && HomingTarget->Implements<UCombatInterface>())
			{
				//获取并赋值追踪目标根组件
				Projectile->ProjectileMovement->HomingTargetComponent = HomingTarget->GetRootComponent();
				//投射物追踪移动速度
				Projectile->ProjectileMovement->HomingAccelerationMagnitude = FMath::FRandRange(MinHomingAccelerationSpeed,MaxHomingAccelerationSpeed);
				//设置自动追踪
				Projectile->ProjectileMovement->bIsHomingProjectile = bIsHoming;
				//加速度调超大
				Projectile->ProjectileMovement->HomingAccelerationMagnitude = 15000.f;

			}
			else
			{
				//如果目标不是敌人没必要追踪 创建这个意义不大 让法术自动飞行即可
				// //如果目标不是敌人，而是墙壁等,会创建一个组件目标 对这个目标释放
				// Projectile->HomingTargetSceneComponent = NewObject<USceneComponent>(USceneComponent::StaticClass());
				// //设置目标组件 的世界位置
				// Projectile->HomingTargetSceneComponent->SetWorldLocation(FinalProjectileTargetLocation);
				// //把目标组件赋值给投射物的追踪组件
				// Projectile->ProjectileMovement->HomingTargetComponent = Projectile->HomingTargetSceneComponent;
			}
		
		}
		
		//设置自动爆炸定时器
		// Projectile->SetAutoExplodeTimer(AutoExplodeTime);
		if (bOnlyHitTarget)
		{
			//设置只碰撞指定目标
			if (HomingTarget && HomingTarget->Implements<UCombatInterface>())
			{
				Projectile->SetOnlyHitSpecificTarget(HomingTarget);
			}
		}
		
		//完成生成过程
		Projectile->FinishSpawning(SpawnTransform);
	}
	

	//这个是向量版本
	// //获取均匀分布 方向数组
	// TArray<FVector> DirectionArray = UBaseAbilitySystemLibrary::EvenlySpacedVectors(Forward,FVector::UpVector,ProjectileSpread,NumProjectiles);
	//
	//
	// for (FVector& Direction : DirectionArray)
	// {
	// 	//绘制调试箭头
	// 	UKismetSystemLibrary::DrawDebugArrow(GetAvatarActorFromActorInfo(),
	// 		SocketLocation,
	// 		SocketLocation + Direction * 75.f,
	// 		5,FLinearColor::Red,120,1);
	// }
	 
}
